<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 
    类封装 
    class（类）是构造函数的【语法糖】：class的本质就是构造函数，只是写法上更简洁
    -->
    <script>
        /*         
        封装一个作者类Author
        ·属性：姓名，作品集（字符串数组）
        ·方法：创作（抽象方法：一行代码都没有，等子类自己去实现）（产出文艺作品） 
        */
        class Author {
            /* 构造器：创建与类同名的实例 */
            constructor(name, artworks = []) {
                this.name = name
                this.artworks = artworks
            }

            /* 实例方法：所有实例共享同一个函数的内存 */
            chuangzuo() {
                console.log(`${this.name}正在创作，具体请子类自行实现...`);
            }

            xinshang(artworkName) {
                console.log(`${this.name}正在欣赏文艺作品《${artworkName}》`);
            }
        }

    </script>

    <!-- 类继承 -->
    <script>
        /* 实现作者子类：导演Director，实现创作方法，产出电影实例 */
        // 声明Director继承于父类Author（默认拥有父类的全部属性和方法）
        class Director extends Author {

            // 导演除了有name, artworks以外 还有自己的潜规则
            constructor(name, artworks, qianguize = null) {
                // 继承父类的name, artworks（不重写constructor的时候默认继承）
                // 如果重写constructor 则必须手动继承一下
                super(name, artworks)

                // 绑定独有的属性在实例身上
                this.qianguize = qianguize
            }

            /* 默认完成对父类所有实例方法的继承*/

            // 导演除了会创作和欣赏以外，还会拍片
            shoot(movieName = "未知片名", type = "未知类型") {
                console.log(`${this.name}正在拍摄${type}片《${movieName}》`);
            }

            // 导演的创作就是拍片（覆盖/重写/覆写/override父类的创作方法）
            chuangzuo() {
                // 继承父类的默认实现
                // super.chuangzuo()
                this.shoot()
            }

            /* 静态成员：本质上都是写在类的作用域中的普通变量和方法 */

            /* 类的静态属性（与具体实例无关）（通过类名进行访问） */
            static zhiye = "导演"

            static add(a, b) {
                return a + b
            }

            /* 类的静态方法（与具体实例无关）（通过类名进行访问） */
            static eat() {
                /* 静态方法中的this是当前类 */
                /* 无法通过类的this去访问【实例属性/实例方法】 */
                /* 静态方法只能访问到静态成员（属性/方法） */
                console.log("导演吃饭都一个鸟样", this, this.zhiye, this.add(2, 3));

                // 无法访问【实例属性/实例方法】
                console.log(this.chuangzuo);
            }

        }

        /* 创建类的实例 */
        const gqj = new Director("宫崎骏", [], "潜规则二次元人物")

        /* 通过实例去访问【实例属性】【实例方法】 */
        console.log(gqj);
        console.log(gqj.name, gqj.qianguize);

        /* 通过实例去访问【实例属性】【实例方法】 */
        gqj.chuangzuo()
        gqj.xinshang("多来A梦")
        gqj.shoot("天空之城", "动画")

        /* 访问类的静态成员 */
        console.log(Director.zhiye);
        Director.eat()

    </script>

</body>

</html>